---
title: Configuration.muxHTTP()
api: Configuration.muxHTTP
---

## Description

<Summary/>

<FilterDiagram
  name="muxHTTP"
  input="Message"
  output="Message"
  subInput="Data"
  subOutput="Data"
  subType="mux"
/>

A _muxHTTP_ filter does the following:

- At the input to a _muxHTTP_ filter, an HTTP request is merged to a sub-pipeline that is shared by multiple _muxHTTP_ filters
- At the input to the shared sub-pipeline, HTTP requests from multiple _muxHTTP_ filters are encoded and **multiplexed** into one single _Data_ stream
- At the output from the shared sub-pipeline, _Data_ stream is de-multiplexed and decoded before individual responses are distributed back to their corresponding _muxHTTP_ filters
- At the output from the _muxHTTP_ filter, out come an HTTP response as a _Message_

Multiple _muxHTTP_ filters can have one shared sub-pipeline, in which many HTTP requests and responses are multiplexed. Compare this to [demuxHTTP()](/reference/api/Configuration/demuxHTTP).

### Stream sharing

You can control where a _mux_ filter merges its input _Message_ to by specifying a _"merging target"_. It can be a value of any type or a function that returns it. Filters with the same _merging target_ share and merge to the same sub-pipeline.

> Merging only happens among filters coming from the same place in the same pipeline layout. Two filters from different pipeline layouts or different places in the same pipeline layout will never merge to the same sub-pipeline, even when they have the same _merging target_.

### Sub-pipeline lifecycle

Since the sub-pipeline is shared by multiple _mux_ filter instances, it won't be closed until the last _mux_ ends. After all _mux_ filter instances sharing it are done, the sub-pipeline will wait for 60 seconds to ensure no more new _mux_ filters come and merge to it. You can change this waiting time by the _maxIdle_ option in the _options_ parameter. It can be either a number in seconds or a string with a unit suffix such as `'s'`, `'m'`, `'h'`, `'d'`.

> When the _merging target_ is an object, it will be a _weak ref_, just like a key in a [WeakMap](https://developer.mozilla.org/docs/Web/JavaScript/Guide/Keyed_collections#weakmap_object). When the object is dead, so is the sub-pipeline being weakly referenced by the object, regardless of the _idleTime_ option.

### HTTP versions

You can select between HTTP/1.1 and HTTP/2 by using the option _version_ in the _options_ parameter. It can be 1 for HTTP/1.1, or 2 for HTTP/2. You can also specify a callback function that gets called at session start and returns the desired protocol version. Default value is 1.

#### Multiplexing in HTTP/1.1

In HTTP/1.1, multiplexing is done by [HTTP pipelining](https://en.wikipedia.org/wiki/HTTP_pipelining). A message queue is used internally by each group of _muxHTTP_ filters sharing the same sub-pipeline, so that each filter can pick the right response for its request from the sub-pipeline's output.

#### Multiplexing in HTTP/2

In HTTP/2, multiplexing is inherently supported by the protocol itself. With HTTP/2, every _muxHTTP_ filter runs a dedicated _virtual stream_ in an HTTP/2 transport stream. There is no shared queue to wait as in HTTP/1.1, so responses to the requests can arrive out of order without having to wait for each other.

### Chunked transfer

When encoding an HTTP/1.x request, the [Content-Length](https://developer.mozilla.org/docs/Web/HTTP/Headers/Content-Length) header needs to come before the body, so _muxHTTP_ has to buffer the entire body until it sees a _MessageEnd_ event, only by then can the filter output a value for _Content-Length_ header, followed by the previously buffered body.

The buffering is limited to 4KB by default. When the buffered data is over 4KB, the encoder will opt for [chunked encoding](https://developer.mozilla.org/docs/Web/HTTP/Headers/Transfer-Encoding#chunked_encoding), where a _Content-Length_ header is no longer needed. You can change this limit by the option _bufferSize_ in the _options_ parameter.

## Syntax

``` js
pipy()
  .pipeline()
  .muxHTTP().to(
    subPipelineLayout
  )

pipy()
  .pipeline()
  .muxHTTP(
    () => whereToMerge()
  ).to(
    subPipelineLayout
  )

pipy()
  .pipeline()
  .muxHTTP({
    maxIdle,
    maxQueue,
    bufferSize,
    version,
  }).to(
    subPipelineLayout
  )

pipy()
  .pipeline()
  .muxHTTP(
    () => whereToMerge(),
    {
      maxIdle,
      maxQueue,
      bufferSize,
      version,
    }
  ).to(
    subPipelineLayout
  )
```

## Parameters

<Parameters/>

## Example

``` js
pipy()

  .listen(8000)                       // Accept TCP connection on port 8000
  .demuxHTTP().to(                    // De-multiplex and decode HTTP requests
    $=>$.muxHTTP().to(                // Encode and multiplex the request into a shared TCP stream
      $=>$.connect('localhost:8080')  // Send to and receive from localhost:8080
    )
  )
```

## See Also

* [Configuration](/reference/api/Configuration)
* [demux()](/reference/api/Configuration/demux)
* [demuxQueue()](/reference/api/Configuration/demuxQueue)
* [demuxHTTP()](/reference/api/Configuration/demuxHTTP)
* [merge()](/reference/api/Configuration/merge)
* [muxQueue()](/reference/api/Configuration/muxQueue)
* [serveHTTP()](/reference/api/Configuration/serveHTTP)
